package com.spoto.oa.util;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;

import com.spoto.oa.dao.SalesDao;
import com.spoto.oa.dao.impl.ProductDaoImpl;
import com.spoto.oa.dao.impl.SalesDaoImpl;
import com.spoto.oa.model.Sales;

public class ChartUtil {
	// 字体
	private static final Font PLOT_FONT = new Font("宋体", Font.BOLD, 15);
	private static final int YEAR_BEGIN = 2009;

	/**
	 * 创建数据集合
	 * 
	 * @return CategoryDataset对象
	 */
	public static CategoryDataset createDataSet(Date dateBegin, Date dateEnd,
			String creator, boolean role) {
		DefaultCategoryDataset dataSet = new DefaultCategoryDataset();
		ProductDaoImpl proDao = new ProductDaoImpl();
		List<String> types = proDao.getType();
		SalesDao salesDao = new SalesDaoImpl();
		for (int i = 0; i < types.size(); i++) {
			List<Sales> tmpSales = null;
			if (dateBegin == null || dateEnd == null) {
				tmpSales = salesDao.getSalesByProType(types.get(i), creator,
						role);
			} else {
				tmpSales = salesDao.getSalesByTime(dateBegin, dateEnd, types
						.get(i), creator, role);
			}
			float sum = 0;
			for (int j = 0; j < tmpSales.size(); j++) {
				sum = sum
						+ (tmpSales.get(j).getNumbers() * tmpSales.get(j)
								.getRealPrice());
			}
			dataSet.addValue(sum, "销售价格", types.get(i));
		}
		return dataSet;
	}

	/**
	 * 创建折线集合对象
	 * 
	 * @param dateBegin
	 * @param dateEnd
	 * @param creator
	 * @param type
	 * @param role
	 * @return
	 */
	public static CategoryDataset createLineDataSet(Date dateBegin,
			Date dateEnd, String creator, String type, boolean role) {
		DefaultCategoryDataset dataSet = new DefaultCategoryDataset();
		ProductDaoImpl proDao = new ProductDaoImpl();
		List<String> types = proDao.getType();
		SalesDao salesDao = new SalesDaoImpl();
		List<Sales> tmpSales = null;
		Calendar calCur = Calendar.getInstance();
		java.util.Date dateCur = new java.util.Date();
		calCur.setTime(dateCur);
		int yearCur = calCur.get(Calendar.YEAR);
		// 格式化时间
		SimpleDateFormat dateFm = new SimpleDateFormat("MM.dd");
		SimpleDateFormat monthFm = new SimpleDateFormat("yy.MM");
		// 默认按年检索
		if ((dateBegin == null || dateEnd == null) && !type.equals("season")) {
			type = "year";
		}
		if (type != null) {
			// 按天检索
			if (type.equals("day")) {
				// 遍历类型
				for (int i = 0; i < types.size(); i++) {
					// 遍历时间求和
					for (Date tmpDate = dateBegin; tmpDate.before(dateEnd); tmpDate = DateUtil
							.getNextDate(tmpDate)) {
						tmpSales = salesDao.getSalesByTime(tmpDate, tmpDate,
								types.get(i), creator, role);
						float sum = getSalesPriceSum(tmpSales);
						dataSet.addValue(sum, types.get(i), dateFm
								.format(tmpDate));
					}
				}
			} else if (type.equals("month")) {
				for (int i = 0; i < types.size(); i++) {
					// 遍历时间求和
					for (Date tmpDate = dateBegin; tmpDate.before(dateEnd); tmpDate = DateUtil
							.getNextMonth(tmpDate)) {
						tmpSales = salesDao.getSalesByTime(DateUtil
								.getFirstDayOfMonth(tmpDate), DateUtil
								.getLastDayOfMonth(tmpDate), types.get(i),
								creator, role);
						float sum = getSalesPriceSum(tmpSales);
						dataSet.addValue(sum, types.get(i), monthFm
								.format(tmpDate));
					}
				}
			} else if (type.equals("season")) {
				for (int i = 0; i < types.size(); i++) {
					for (int tmpYear = YEAR_BEGIN; tmpYear <= yearCur; tmpYear++) {
						for (int quarter = 1; quarter <= 4; quarter++) {
							tmpSales = salesDao.getSalesByTime(DateUtil
									.buildDate(tmpYear, quarter * 3 - 2, 1),
									DateUtil.getLastDayOfQuarter(tmpYear,
											quarter), types.get(i), creator,
									role);
							float sum = getSalesPriceSum(tmpSales);
							dataSet.addValue(sum, types.get(i), tmpYear + "年第"
									+ quarter + "季度");
						}
					}
				}
				return dataSet;
			} else if (type.equals("year")) {
				for (int i = 0; i < types.size(); i++) {
					for (int tmpYear = YEAR_BEGIN; tmpYear <= yearCur; tmpYear++) {
						tmpSales = salesDao.getSalesByTime(DateUtil
								.getFirstDayOfYear(tmpYear), DateUtil
								.getLastDayOfYear(tmpYear), types.get(i),
								creator, role);
						float sum = getSalesPriceSum(tmpSales);
						dataSet.addValue(sum, types.get(i),
								new Integer(tmpYear).toString());
					}
				}
			}
		}

		return dataSet;
	}

	private static float getSalesPriceSum(List<Sales> tmpSales) {
		float sum = 0;
		for (int j = 0; j < tmpSales.size(); j++) {
			sum = sum
					+ (tmpSales.get(j).getNumbers() * tmpSales.get(j)
							.getRealPrice());
		}
		return sum;
	}

	/**
	 * 生成制图对象
	 * 
	 * @param
	 * @return JFreeChart对象
	 */
	public static JFreeChart createChart(String style, Date dateBegin,
			Date dateEnd, String type, String creator, boolean role) {
		JFreeChart chart = null;
		SimpleDateFormat monthFm = new SimpleDateFormat("yyyy.MM");
		SimpleDateFormat dateFm = new SimpleDateFormat("yyyy.MM.dd");
		String title = "历年产品销售情况统计报表";
		if (dateBegin != null && dateEnd != null) {
			if (type.equals("month")) {
				title = monthFm.format(dateBegin) + "-"
						+ monthFm.format(dateEnd) + "月度销售情况统计报表";
			} else if (type.equals("day")) {
				title = dateFm.format(dateBegin) + "-" + dateFm.format(dateEnd)
						+ "销售情况统计报表";
			}
		} else if (dateBegin != null && dateEnd == null) {
			title = dateBegin.toString() + "至今产品销售情况统计报表";
		}
		if (type.equals("season")
				&& (style.equals("line3D") || style.equals("line"))) {
			title = "历年季度销售情况统计报表";
		}
		String xTitle = "产品类型";
		String yTitle = "销售总价";
		if (style.equals("line3D")) {

			chart = ChartFactory.createLineChart3D(title, // 图表标题
					xTitle, // X轴标题
					yTitle,
					// Y轴标题
					createLineDataSet(dateBegin, dateEnd, creator, type, role),
					// 绘图数据集
					PlotOrientation.VERTICAL,
					// 绘制方向
					true,
					// 显示图例
					true,
					// 采用标准生成器
					false
			// 是否生成超链接
					);
		} else if (style.equals("line")) {
			chart = ChartFactory.createLineChart(title, // 图表标题
					xTitle, // X轴标题
					yTitle, // Y轴标题
					createLineDataSet(dateBegin, dateEnd, creator, type, role), // 绘图数据集
					PlotOrientation.VERTICAL, // 绘制方向
					true, // 是否显示图例
					true, // 是否采用标准生成器
					false // 是否生成超链接
					);
		} else if (style.equals("bar3D")) {
			chart = ChartFactory.createBarChart3D(title, // 图表标题
					xTitle, // X轴标题
					yTitle, // Y轴标题
					createDataSet(dateBegin, dateEnd, creator, role), // 绘图数据集
					PlotOrientation.VERTICAL, // 绘制方向
					true, // 是否显示图例
					true, // 是否采用标准生成器
					false // 是否生成超链接
					);
		} else if (style.equals("bar")) {
			chart = ChartFactory.createBarChart(title, // 图表标题
					xTitle, // X轴标题
					yTitle, // Y轴标题
					createDataSet(dateBegin, dateEnd, creator, role), // 绘图数据集
					PlotOrientation.VERTICAL, // 绘制方向
					true, // 是否显示图例
					true, // 是否采用标准生成器
					false // 是否生成超链接
					);
		}

		// 设置标题字体
		chart.getTitle().setFont(new Font("隶书", Font.BOLD, 23));
		// 设置图例类别字体
		chart.getLegend().setItemFont(new Font("宋体", Font.BOLD, 15));
		chart.setBackgroundPaint(new Color(192, 228, 106)); // 设置背景色
		// 获取绘图区对象
		CategoryPlot plot = chart.getCategoryPlot();
		plot.getDomainAxis().setLabelFont(PLOT_FONT);
		// 设置横轴字体
		plot.getDomainAxis().setTickLabelFont(PLOT_FONT);
		// 设置坐标轴标尺值字体
		plot.getRangeAxis().setLabelFont(PLOT_FONT);
		// 设置纵轴字体
		plot.setBackgroundPaint(Color.WHITE);
		// 设置绘图区背景色
		plot.setRangeGridlinePaint(Color.RED);
		// 设置水平方向背景线颜色
		plot.setRangeGridlinesVisible(true);
		// 设置是否显示水平方向背景线,默认值为true
		plot.setDomainGridlinePaint(Color.RED);
		// 设置垂直方向背景线颜色
		plot.setDomainGridlinesVisible(true);
		// 设置是否显示垂直方向背景线,默认值为false
		if (style.equals("line") || style.equals("line3D")) {
			// 获取折线对象
			LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot
					.getRenderer();
			// BasicStroke realLine = new BasicStroke(1.6f); // 设置实线
			float dashes[] = { 8.0f }; // 定义虚线数组
			BasicStroke brokenLine = new BasicStroke(1.6f, // 线条粗细
					BasicStroke.CAP_SQUARE, // 端点风格
					BasicStroke.JOIN_MITER, // 折点风格
					8.f, // 折点处理办法
					dashes, // 虚线数组
					0.0f); // 虚线偏移量
			renderer.setSeriesStroke(1, brokenLine);
			// 利用虚线绘制制
			CategoryAxis domainAxis = plot.getDomainAxis();
			domainAxis.setCategoryLabelPositions(CategoryLabelPositions
					.createUpRotationLabelPositions(Math.PI / 3.0));
		} else {
			// 获取柱状对象
			BarRenderer renderer = (BarRenderer) plot.getRenderer();
			renderer.setDrawBarOutline(false);

			// set up gradient paints for series...
			GradientPaint gp0 = new GradientPaint(0.0f, 0.0f, Color.blue, 0.0f,
					0.0f, new Color(0, 0, 64));
			renderer.setSeriesPaint(0, gp0);
		}
		return chart;
	}
}